package top.readhub.wopei.manager.zk;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.List;

/**
 * Created by daervin on 2021/6/7
 */
@Component
public class ZKClient {
    private static final Logger logger = LoggerFactory.getLogger(ZKClient.class);

    @Value("${zookeeper.address}")
    private String address;
    @Value("${zookeeper.timeout}")
    private int timeout;

    private CuratorFramework zkClient;

    @PostConstruct
    public void initZKClient() {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString(address)
                .retryPolicy(retryPolicy)
                .sessionTimeoutMs(6000)
                .connectionTimeoutMs(timeout)
                .namespace("wopei")
                .build();
        client.start();
        zkClient = client;
    }

    public void setData(String path, String data) throws Exception {
        Stat stat = zkClient.checkExists().forPath(path);
        if (stat == null) {
            zkClient.create().creatingParentsIfNeeded().forPath(path);
            logger.info("create path:{}", path);
        }
        this.zkClient.setData().forPath(path, data.getBytes());
        logger.info("set data path:{}，data:{}", path, data);
    }

    public String getData(String path) throws Exception {
        byte[] bytes = this.zkClient.getData().forPath(path);
        return new String(bytes, "utf-8");
    }

    public void create(String path) throws Exception {
        Stat stat = zkClient.checkExists().forPath(path);
        if (stat == null) {
            zkClient.create().creatingParentsIfNeeded().forPath(path);
            logger.info("create path:{}", path);
        }
    }

    public List<String> getChildren(String path) throws Exception {
        Stat stat = zkClient.checkExists().forPath(path);
        if (stat != null) {
            return zkClient.getChildren().forPath(path);
        }
        return Collections.emptyList();
    }

    public void delete(String path) throws Exception {
        Stat stat = zkClient.checkExists().forPath(path);
        if (stat != null) {
            zkClient.delete().deletingChildrenIfNeeded().forPath(path);
            logger.info("delete path:{}", path);
        }
    }
}
